#include "Example_Mass_Spring_Simulation.h"
#include <sxOpenGL_DefaultCameraRenderer.h>
#include <sxMassSpringSimulationController.h>
#include <sxMassSpringMesh.h>
#include <sxOpenGL_DefaultMassSpringMeshRenderer.h>
#include <sxOpenGL_Canvas.h>
#include <sxOpenGL_PickingController.h>

/* Storage Types */
#include <sxOBJ_VegaMassSpringMeshStorage.h>
#include <sxVega_TetgenMassSpringMeshStorage.h>

/* Sx library types. */
using Sx::OpenGL::Graphics::Contexts::OpenGL_Context;
using Sx::QtInterface::QOpenGL_Viewport;
using Sx::Simulation::Simulations::MassSpringSimulation;
using Sx::Simulation::Interface::MassSpringSimulationController;
using Sx::OpenGL::Graphics::Objects::Rendering::OpenGL_DefaultCameraRenderer;
using Sx::Simulation::Objects::MassSpringMesh;
using Sx::Vega::Storage::OBJ_VegaMassSpringMeshStorage;
using Sx::Simulation::Objects::Rendering::OpenGL_DefaultMassSpringMeshRenderer;
using Sx::OpenGL::Graphics::Picking::OpenGL_PickingController;
using Sx::OpenGL::Interface::OpenGL_Canvas;

Example_Mass_Spring_Simulation::Example_Mass_Spring_Simulation(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) {
	ui.setupUi(this);

	//--------------------------------------------------------------------------
	// Initialize an OpenGL Viewport
	//--------------------------------------------------------------------------
	this->openglContext = std::make_shared<OpenGL_Context>();

	this->openglViewport = new QOpenGL_Viewport(this, this->openglContext);
	this->openglViewport->setRealtime(true);
	this->openglViewport->initialize();

	//--------------------------------------------------------------------------
	// Create a new mass-spring simulation.
	//--------------------------------------------------------------------------
	this->massSpringSimulation = std::make_shared<MassSpringSimulation>();
	this->massSpringSimulation->setTimeStepType(Sx::Simulation::FIXED);
	this->massSpringSimulation->setTimeStep(1.0 / 1000.0f);

	//--------------------------------------------------------------------------
	// Setup a new mass-spring controller.
	// Controller ownership is transfered to the OpenGL Viewport.
	//--------------------------------------------------------------------------
	this->mssController = std::make_shared<MassSpringSimulationController>(this->openglViewport, std::make_shared<OpenGL_Canvas>(this->openglContext), std::make_shared<OpenGL_PickingController>(), std::make_shared<OpenGL_DefaultCameraRenderer>(this->openglContext), this->massSpringSimulation);
	this->mssController->initialize();

	//--------------------------------------------------------------------------
	// OBJ-Based Mass-Spring Mesh
	//--------------------------------------------------------------------------
	this->msm = MassSpringMesh::Load(std::make_shared<OBJ_VegaMassSpringMeshStorage>().get(), std::make_shared<OpenGL_DefaultMassSpringMeshRenderer>(openglContext), "cloth.obj");
	this->msm->setSubsteps(10);

	this->massSpringSimulation->add(this->msm);

	this->openglViewport->setController(this->mssController);
}

Example_Mass_Spring_Simulation::~Example_Mass_Spring_Simulation() {}

void Example_Mass_Spring_Simulation::resizeEvent(QResizeEvent* e) {
	if ( this->openglViewport == nullptr ) return;
	this->openglViewport->resize(this->width(), this->height());
}

void Example_Mass_Spring_Simulation::mousePressEvent(QMouseEvent* e) {
	if ( this->msm == nullptr ) return;
}

void Example_Mass_Spring_Simulation::mouseReleaseEvent(QMouseEvent* e) {}
